#pragma once

#ifdef GK_DEVICE_OPENGL

#define ASSIGN(p,v)	if (p) { *p = v; }

namespace gk
{
	namespace TypeConversion
	{
		inline BufferFormat::Enum ConvertBufferFormat(GLuint bufferFormat, GLuint* cmptCount = 0, GLenum* cmptType = 0)
		{
			switch (bufferFormat)
			{
			case GL_RGBA:					ASSIGN(cmptType,GL_UNSIGNED_BYTE);	ASSIGN(cmptCount,4); return BufferFormat::R8G8B8A8;
			case GL_RGB:					ASSIGN(cmptType,GL_UNSIGNED_BYTE);	ASSIGN(cmptCount,3); return BufferFormat::R8G8B8;
			case GL_RGBA32F:				ASSIGN(cmptType,GL_FLOAT);			ASSIGN(cmptCount,4); return BufferFormat::RGBA32F;
			case GL_RGBA16F:				ASSIGN(cmptType,GL_FLOAT);			ASSIGN(cmptCount,4); return BufferFormat::RGBA16F;
			case GL_DEPTH_COMPONENT16:		ASSIGN(cmptType,GL_SHORT);			ASSIGN(cmptCount,2); return BufferFormat::D16;
			case GL_DEPTH_COMPONENT24:		ASSIGN(cmptType,GL_INT);			ASSIGN(cmptCount,3); return BufferFormat::D24S8;
			default:						return BufferFormat::Invalid;
			}
		}

		inline void ConvertBufferFormat(BufferFormat::Enum bufferFormat, GLuint* cmptInternalFormat, GLuint* cmptFormat = 0, GLenum* cmptType = 0)
		{
			switch (bufferFormat)
			{
			case BufferFormat::R8G8B8A8:	ASSIGN(cmptType,GL_UNSIGNED_BYTE);	ASSIGN(cmptFormat,GL_RGBA);				ASSIGN(cmptInternalFormat,GL_RGBA);					break;
			case BufferFormat::R8G8B8:		ASSIGN(cmptType,GL_UNSIGNED_BYTE);	ASSIGN(cmptFormat,GL_RGB);				ASSIGN(cmptInternalFormat,GL_RGB);					break;		
			case BufferFormat::RGBA32F:		ASSIGN(cmptType,GL_FLOAT);			ASSIGN(cmptFormat,GL_RGBA16F);			ASSIGN(cmptInternalFormat,GL_RGBA32F);				break;
			case BufferFormat::RGBA16F:		ASSIGN(cmptType,GL_FLOAT);			ASSIGN(cmptFormat,GL_RGBA32F);			ASSIGN(cmptInternalFormat,GL_RGBA16F);				break;
			case BufferFormat::D16:			ASSIGN(cmptType,GL_UNSIGNED_BYTE);	ASSIGN(cmptFormat,GL_DEPTH_COMPONENT);	ASSIGN(cmptInternalFormat,GL_DEPTH_COMPONENT16);	break;
			case BufferFormat::D24S8:		ASSIGN(cmptType,GL_UNSIGNED_BYTE);	ASSIGN(cmptFormat,GL_DEPTH_COMPONENT);	ASSIGN(cmptInternalFormat,GL_DEPTH_COMPONENT24);	break;
			case BufferFormat::D32:			ASSIGN(cmptType,GL_UNSIGNED_BYTE);	ASSIGN(cmptFormat,GL_DEPTH_COMPONENT);	ASSIGN(cmptInternalFormat,GL_DEPTH_COMPONENT32);	break;
			}
		}

		inline GLuint ConvertClearType(ClearType::Enum clearType)
		{
			GLuint res = 0;
			res |= (clearType & ClearType::ColourTarget) ? GL_COLOR_BUFFER_BIT : 0;
			res |= (clearType & ClearType::DepthTarget) ? GL_DEPTH_BUFFER_BIT : 0;
			res |= (clearType & ClearType::StencilTarget) ? GL_STENCIL_BUFFER_BIT : 0;
			return res;
		}
	}
}

#endif // GK_DEVICE_OPENGL